#pragma once

#include "BasicObject.h"
#include "Agent.h"
#include "typdefs.h"
#include "TemplateFactory.h"
#include "event.h"
#include "mathhelper.h"
#include "action.h"


namespace BAA
{
	class Action;

	class Agent;
	typedef std::map<int,  Agent*, std::less<int>>				AgentIDMap;
	typedef std::map< std::string,  Agent*, std::less<std::string>>		AgentNameMap;

	class Event;
	typedef std::map< std::string, std::vector<Event*>>					AgentNameEventMap;

	class World:public BasicObject
	{
	public:
		static World * getInstance();
		~World()
		{

		}

		inline void Create()
		{
			mAgentIDMap = new AgentIDMap();
			mAgentNameMap = new AgentNameMap();
		}

		inline void Initialize()
		{
			// initialize each agent
			for(AgentIDMap::const_iterator i = mAgentIDMap->begin(); i != mAgentIDMap->end(); ++i)
			{


			}
		}

		inline void Clear()
		{
			mAgentIDMap->clear();
			mAgentNameMap->clear();

		}

		inline const Agent * GetAgent(int ID)
		{
			return (*mAgentIDMap)[ID];
		}

		//inline Agent * GetAgent(const string * name)
		//{
		//	return (*mAgentNameMap)[name];
		//}

		inline void AddAgent(Agent * agent, int ID, std::string name)
		{
			(*mAgentIDMap)[ID]= agent;
			(*mAgentNameMap)[name] = agent;
		}


		float DistanceBetween(Agent* a, Agent* b);

		float DistanceBetween(Agent* a, Vector3* b);

		//////////////////////////////////////////////////////////////////////////
		// implement remove methods
		//////////////////////////////////////////////////////////////////////////


		BAA::TemplateFactory* Templates() { return &mTemplates; }
		void Templates(BAA::TemplateFactory val) { mTemplates = val; }

		std::vector<Event*>* getEventsForAgent(std::string name)
		{
			return (&(mAgentEvents[name]));
		}

		void CreateAgentEvent(Agent * agent, Action * action);

	private:
		AgentIDMap *    mAgentIDMap;
		AgentNameMap *  mAgentNameMap;

		TemplateFactory mTemplates;

		AgentNameEventMap mAgentEvents;

		static World* pInstance;

	protected:
		World(const std::string name):BasicObject(name){}

	};// end class


}// end namespace
